package com.wenx.v3system.modular.cloud.controller;

import com.wenx.base.rest.BaseRestController;
import com.wenx.v3core.response.R;
import com.wenx.v3secure.annotation.RequiresPermissions;
import com.wenx.v3secure.enums.SystemPermission;
import com.wenx.v3system.modular.cloud.domain.dto.SysUserDto;
import com.wenx.v3system.modular.cloud.domain.maps.SysUserMap;
import com.wenx.v3system.modular.cloud.domain.po.SysUser;
import com.wenx.v3system.modular.cloud.domain.query.SysUserQuery;
import com.wenx.v3system.modular.cloud.service.SysUserRestService;
import com.wenx.v3system.modular.cloud.service.SysUserPermissionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static com.wenx.v3secure.annotation.RequiresPermissions.Logical.OR;

/**
 * 用户管理控制器
 * 提供用户CRUD、批量操作、状态管理、权限验证等功能
 * 整合用户权限相关的所有功能接口
 * 
 * @author wenx
 * @since 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/api/v3/sys/users")
@Tag(name = "用户管理", description = "用户管理相关接口")
public class SysUserRestController extends BaseRestController<SysUserDto, SysUserQuery, SysUserRestService> {

    private final SysUserPermissionService userPermissionService;

    /**
     * 构造函数注入，避免循环依赖
     */
    public SysUserRestController(SysUserRestService service,
                                SysUserPermissionService userPermissionService) {
        super(service);
        this.userPermissionService = userPermissionService;
    }

    @Override
    @PostMapping("/page")
    @Operation(summary = "分页查询用户", description = "根据查询条件分页获取用户列表")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_READ_CODE}, logical = OR)
    public R page(@RequestBody SysUserQuery query) {
        return R.ok(service.page(query));
    }

    /**
     * 获取所有用户（不分页）
     */
    @GetMapping("/all")
    @Operation(summary = "获取所有用户", description = "获取系统中所有用户列表")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_READ_CODE}, logical = OR)
    public R getAllUsers() {
        // 使用MyBatis-Plus的list()方法获取所有用户，然后转换为DTO
        List<SysUser> users = service.list();
        List<SysUserDto> userDtos = users.stream()
                .map(user -> SysUserMap.INSTANCE.toDto(user))
                .collect(Collectors.toList());
        return R.ok(userDtos);
    }

    @Override
    @GetMapping("/get/{id}")
    @Operation(summary = "获取用户详情", description = "根据用户ID获取用户详细信息")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_READ_CODE}, logical = OR)
    public R get(@PathVariable Serializable id) {
        return R.ok(service.get(id));
    }

    @Override
    @PostMapping("/add")
    @Operation(summary = "新增用户", description = "创建新的用户")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_ALL_CODE}, logical = OR)
    public R add(@RequestBody SysUserDto dto) {
        service.add(dto);
        return R.ok();
    }

    @Override
    @PutMapping("/update")
    @Operation(summary = "更新用户", description = "更新用户信息")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_ALL_CODE}, logical = OR)
    public R update(@RequestBody SysUserDto dto) {
        service.update(dto);
        return R.ok();
    }

    @Override
    @DeleteMapping("/delete/{id}")
    @Operation(summary = "删除用户", description = "根据用户ID删除用户")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_ALL_CODE}, logical = OR)
    public R delete(@PathVariable Serializable id) {
        service.delete(id);
        return R.ok();
    }

    /**
     * 根据用户名获取用户
     */
    @GetMapping("/username/{username}")
    @Operation(summary = "根据用户名获取用户", description = "根据用户名获取用户信息")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_READ_CODE}, logical = OR)
    public R getUserByUsername(@PathVariable String username) {
        return R.ok(service.getUserByUsername(username));
    }

    /**
     * 获取用户权限列表（增强版）
     */
    @GetMapping("/{userId}/permissions")
    @Operation(summary = "获取用户权限", description = "获取用户的所有权限（包括直接分配和通过角色继承的权限）")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_READ_CODE}, logical = OR)
    public R getUserPermissions(@PathVariable Long userId) {
        Set<String> permissions = userPermissionService.getUserPermissions(userId);
        return R.ok(permissions);
    }

    /**
     * 获取用户角色列表
     */
    @GetMapping("/{userId}/roles")
    @Operation(summary = "获取用户角色", description = "获取用户的所有角色")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_READ_CODE}, logical = OR)
    public R getUserRoles(@PathVariable Long userId) {
        Set<Long> roles = userPermissionService.getUserRoles(userId);
        return R.ok(roles);
    }

    /**
     * 获取用户可访问的菜单列表
     */
    @GetMapping("/{userId}/menus")
    @Operation(summary = "获取用户菜单", description = "获取用户可访问的菜单列表")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_READ_CODE}, logical = OR)
    public R getUserMenus(@PathVariable Long userId) {
        Set<Long> menus = userPermissionService.getUserMenus(userId);
        return R.ok(menus);
    }

    /**
     * 检查用户权限
     */
    @GetMapping("/{userId}/has-permission")
    @Operation(summary = "检查用户权限", description = "检查用户是否拥有指定权限")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_READ_CODE}, logical = OR)
    public R hasPermission(@PathVariable Long userId, @RequestParam String permission) {
        boolean result = userPermissionService.hasPermission(userId, permission);
        return R.ok(result);
    }

    /**
     * 分配用户角色
     */
    @PostMapping("/{userId}/assign-roles")
    @Operation(summary = "分配用户角色", description = "为用户分配角色列表")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_ALL_CODE}, logical = OR)
    public R assignRoles(@PathVariable Long userId, @RequestBody List<Long> roleIds) {
        userPermissionService.assignRolesToUser(userId, roleIds);
        return R.ok("用户角色分配成功");
    }

    /**
     * 移除用户角色
     */
    @DeleteMapping("/{userId}/roles")
    @Operation(summary = "移除用户角色", description = "移除用户的所有角色")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_ALL_CODE}, logical = OR)
    public R removeUserRoles(@PathVariable Long userId) {
        Set<Long> currentRoles = userPermissionService.getUserRoles(userId);
        userPermissionService.removeUserRoles(userId, List.copyOf(currentRoles));
        return R.ok("用户角色移除成功");
    }

    /**
     * 清除用户权限缓存
     */
    @DeleteMapping("/{userId}/cache")
    @Operation(summary = "清除用户缓存", description = "清除指定用户的权限缓存")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.SYSTEM_CONFIG_CODE}, logical = OR)
    public R clearUserCache(@PathVariable Long userId) {
        userPermissionService.clearUserPermissionCache(userId);
        return R.ok("用户缓存清除成功");
    }

    /**
     * 检查用户名是否存在
     */
    @GetMapping("/check-username")
    @Operation(summary = "检查用户名", description = "检查用户名是否已存在")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_READ_CODE}, logical = OR)
    public R checkUsername(@RequestParam String username, @RequestParam(required = false) Long excludeId) {
        boolean exists = service.checkUsernameExists(username, excludeId);
        return R.ok(Map.of("exists", exists));
    }

    /**
     * 检查邮箱是否存在
     */
    @GetMapping("/check-email")
    @Operation(summary = "检查邮箱", description = "检查邮箱是否已存在")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_READ_CODE}, logical = OR)
    public R checkEmail(@RequestParam String email, @RequestParam(required = false) Long excludeId) {
        boolean exists = service.checkEmailExists(email, excludeId);
        return R.ok(Map.of("exists", exists));
    }

    /**
     * 根据部门ID查询用户
     */
    @GetMapping("/department/{departmentId}")
    @Operation(summary = "根据部门ID查询用户", description = "根据部门ID获取该部门下的所有用户")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_READ_CODE}, logical = OR)
    public R getUsersByDepartmentId(@PathVariable Long departmentId) {
        List<SysUserDto> users = service.getUsersByDepartmentId(departmentId);
        return R.ok(users);
    }

    /**
     * 获取用户分配数据（角色、部门、团队）
     */
    @GetMapping("/assignment-data")
    @Operation(summary = "获取用户分配数据", description = "获取所有可用的角色、部门、团队列表，用于用户分配")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.USER_READ_CODE}, logical = OR)
    public R getUserAssignmentData() {
        return R.ok(service.getUserAssignmentData());
    }
}
